package controller

import (
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"go-im-server-demo/src/model"
	"go-im-server-demo/src/service"
	"go-im-server-demo/src/utils"
	jwtu "go-im-server-demo/src/utils/jwt"
	"log"
	"net/http"
	"sync"

	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
)

func init() {
}

const (
	VCODEMAP = "vcodemap"
)

var lock *sync.Mutex = &sync.Mutex{}

/**
用户登录
*/
func Login(ctx *gin.Context) {

	var m model.LoginEntity
	err := ctx.BindJSON(&m)
	if err != nil {
		fmt.Println("反序列化失败")
	}

	if utils.IsEmpty(m.GetEmail()) {
		panic(errors.New("邮箱不能为空"))
	}

	if utils.IsEmpty(m.GetVcode()) {
		panic(errors.New("验证码不能为空"))
	}

	session := sessions.Default(ctx)
	vc := session.Get("email")
	if vc == nil {
		panic(errors.New("验证码已失效"))
	}
	//
	if vc.(string) != m.GetVcode() {
		panic(errors.New("验证码输入有误"))
	} else {
		session.Delete("email")
		re := session.Save()
		if re != nil {
			panic(re)
		}
	}

	token, err := service.Login(m.Email)
	if err != nil {
		panic(err)
	}

	result := make(map[string]interface{})
	result["code"] = 200
	result["msg"] = "登陆成功"
	result["token"] = token
	ctx.JSON(200, result)
}

/**
发送验证码
*/
func SendEmail(ctx *gin.Context) {
	bodyEntityMap := make(map[string]interface{})
	err := ctx.BindJSON(&bodyEntityMap)
	if err != nil {
		log.Panic(errors.New("数据体不能为空"))
	}
	email, ok := bodyEntityMap["email"]
	if !ok {
		panic(errors.New("邮箱地址不能为空"))
	}

	vcode := utils.GenerateVcodeOf(6)

	fmt.Printf("[%s]生成的验证码为%s\n", email, vcode)
	session := sessions.Default(ctx)
	if session == nil {
		panic(errors.New("session 获取不到"))
	}
	session.Set("email", vcode)
	err = session.Save()

	go func() {
		// 发送邮件
		err = service.SendEmail(email.(string), vcode)
		if err != nil {
			log.Println("发送失败:", err)
		}
	}()

	ctx.JSON(200, gin.H{
		"code": 200,
		"msg":  "发送成功",
	})

}

func GetUserInfo(ctx *gin.Context) {
	token := ctx.GetHeader("token")
	if token == "" {
		panic(errors.New("请求头中未包含Token"))
	}
	h := jwtu.Default()
	cla, err := h.Verify(token)
	if err != nil {
		fmt.Println("验证token失败", err)
		panic(err)
	}
	err = cla.Valid()
	if err != nil {
		fmt.Println("验证token失败", err)
		panic(err)
	}

	mapC, ok := cla.(jwt.MapClaims)
	if !ok {
		panic(errors.New("未知异常"))
	}

	uid, ok := mapC["uid"]
	if !ok {
		panic(errors.New("未知异常"))
	}

	userInfo, err := service.GetUserInfo(uid.(string))

	data := gin.H{
		"id":         userInfo.ID,
		"email":      userInfo.Email,
		"createTime": userInfo.CreatedAt.Format("2006-01-02 15:04:05"),
		"updateTime": userInfo.UpdateAt.Format("2006-01-02 15:04:05"),
	}
	if userInfo.Name == "" {
		data["name"] = nil
	} else {
		data["name"] = userInfo.Name
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code": "200",
		"data": data,
	})
}
func SetUserInfo(ctx *gin.Context) {
	token := ctx.GetHeader("token")
	if token == "" {
		panic(errors.New("请求头中未包含Token"))
	}
	h := jwtu.Default()
	cla, err := h.Verify(token)
	if err != nil {
		fmt.Println("验证token失败", err)
		panic(err)
	}
	err = cla.Valid()
	if err != nil {
		fmt.Println("验证token失败", err)
		panic(err)
	}

	mapC, ok := cla.(jwt.MapClaims)
	if !ok {
		panic(errors.New("未知异常"))
	}

	uid, ok := mapC["uid"]
	if !ok {
		panic(errors.New("未知异常"))
	}
	u := new(model.User2)
	if err = ctx.BindJSON(u); err != nil {
		panic(err)
	}

	fmt.Printf("uid :%s\nname:%s\n", uid, u.Name)

	err = service.SetUserName(uid.(string), u.Name)
	if err != nil {
		panic(err)
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code": "200",
		"msg":  "修改成功",
	})

}
